package com.sleepsocial.web.connect;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.scribe.builder.ServiceBuilder;
import org.scribe.builder.api.FacebookApi;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.Token;
import org.scribe.model.Verb;
import org.scribe.oauth.OAuthService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.google.appengine.repackaged.org.json.JSONException;
import com.google.appengine.repackaged.org.json.JSONObject;
import com.sleepsocial.authentication.AuthenticationManager;
import com.sleepsocial.logging.Logger;
import com.sleepsocial.persistency.entity.oauth.OauthProvider;
import com.sleepsocial.persistency.entity.oauth.OauthUserProfile;
import com.sleepsocial.persistency.entity.user.Gender;
import com.sleepsocial.persistency.entity.user.UserProfile;

@Controller
@RequestMapping(value = "/connect")
public class FacebookConnector {
    private static final Logger log        = Logger.getInstance(FacebookConnector.class.getName());

    // TODO externalize the key
    private static final String API_KEY    = "6cae5f3ef2d3a131df43464baddbcdd6";
    private static final String API_SECRET = "d42f1df5d7297ee9d758aece0db4daeb";
    private static final String API_URL    = "https://graph.facebook.com/";
    private static final String ABOUT_URL  = API_URL + "me";

    private OAuthService        service;

    public FacebookConnector() {
        service = new ServiceBuilder().apiKey(API_KEY).apiSecret(API_SECRET).provider(FacebookApi.class).build();
    }

    @RequestMapping(value = "/facebook", method = RequestMethod.POST)
    public void connect(HttpServletRequest req, HttpServletResponse res, @RequestParam String access_token, @RequestParam String secret) throws IOException {
        log.i("Connecting to facebook");
        Token accessToken = new Token(access_token, secret);
        OAuthRequest request = new OAuthRequest(Verb.GET, ABOUT_URL);
        service.signRequest(accessToken, request);
        log.i("Sending about request");
        Response response = request.send();
        OauthUserProfile profile = null;
        if (response.getCode() == 200) {
            log.i("Response successful");
            profile = new OauthUserProfile(access_token, secret);
            // TODO externallize this
            profile.setProvider(OauthProvider.FACEBOOK);
            populateProfile(profile, response.getBody());
            log.i("User info got, storing user profile into the datastore");
            UserProfile user = AuthenticationManager.getAuthenticatedUser(req);
            if(user !=null) {
                user.addOauthProfile(profile);
            }else {
                UserProfile.storeOauthUserProfile(profile);
            }
        }

    }

    public boolean populateProfile(OauthUserProfile profile, String json) {
        try {
            log.i("populating user profile");
            JSONObject jsonObject = new JSONObject(json);
            if (profile.getEmail() == null) {
                profile.setEmail(jsonObject.getString("email"));
            }
            if (profile.getEmail().equals(jsonObject.get("email"))) {
                profile.setName(jsonObject.getString("name"));
                profile.setGender(Gender.valueOf(jsonObject.getString("gender").toUpperCase()));
                profile.setPhotoUrl(API_URL + jsonObject.getString("id") + "/picture");
                // TODO implement all fields
                log.i("user profile populated successfully");
                return true;
            } else {
                log.i("user profile not populated, not the same email");
                return false;
            }
        } catch (JSONException e) {
            log.w("exception populating user profile = " + profile, e);
            return false;
        }
    }
}
